package com.android.controller;

import java.util.ArrayList;

import com.android.networking.message.DataMessage;
import com.android.networking.message.DataPacket;

/**
 * Drawer Logic Class - Manages the drawer's control logic.
 * 
 * @author David Alban
 * @version 1.0 
 */
public class DrawerLogic
{
	/**
	 * Player's start time in milliseconds
	 */
	private long startTime;
	/**
	 * Player's end time in milliseconds
	 */
	private long endTime;
	/**
	 * Maximum draw time allowed in milliseconds
	 */
	public static final long DRAW_TIME = 180000;
	/**
	 * Player's draw time in milliseconds
	 */
	private long drawTime;
	/**
	 * Time left for player to draw in milliseconds
	 */
	private long timeLeft;
	/**
	 * Drawer's first data message: 
	 * false = any data message after the first,
	 * true	 = first data message
	 */
	private boolean firstDataMessage;
	/**
	 * Error from data message packet: 
	 * false = data message packet is error free,
	 * true	 = data message packet has errors
	 */
	private boolean dataMessageError;
	/**
	 * Data message sequence number
	 */
    private int sourceSeqNumber;
	/**
	 * Data points path length
	 */
    private int pointsPathLen;
	/**
	 * Array list of points, creates a path
	 */
	private ArrayList pointPath;
	/**
	 * String representation of the word to be drawn.
	 */
	private String word;
	/**
	 * Part of speech of word 
	 * 
	 * Adjective		describes a noun
	 * Adverb			describes a verb, adjective or adverb
	 * Conjunction		joins clauses or sentences or words
	 * Interjection		short exclamation, sometimes inserted into a sentence
	 * Noun				thing or person
	 * Preposition		links a noun to another word
	 * Pronoun			replaces a noun
	 * Verb				action or state
	 */ 
	private String wordType;
	/**
	 * Array of hints on the word 
	 */
	private ArrayList hint;
	/**
	 * String representation of the first hint on the word 
	 */
	private String hint1;
	/**
	 * String representation of the second hint on the word 
	 */
	private String hint2;
	/**
	 * String representation of the guess on the word
	 */
	private String guess;
	/**
	 * Player's guess time in milliseconds
	 */
	private long guessTime;
	/**
	 * Number of hints used by guesser
	 */
	private int hintCount;
	/**
	 * Data message
	 */
	private DataMessage dataMessage;
	/**
	 * Data packet
	 */
	private DataPacket localPack;
	
	/**
	 * Constructor - Initializes the drawer logic class.
	 */
	public DrawerLogic()
	{
		startTime = 0;
		endTime   = 0;
		drawTime  = 0;
		timeLeft  = 0;
		
		firstDataMessage = true;
		dataMessageError = false;
		
		sourceSeqNumber = 0;
		pointsPathLen   = 0;
		pointPath       = null;
		word            = null;
		wordType        = null;
		hint1           = null;
		hint2           = null;
		guess           = null;
		guessTime       = 0;
		hintCount       = 0;

		localPack = new DataPacket();
	}
	
	/**
	 * Accessor Method - Returns the word to be drawn.
	 * @return	word		Word to be drawn
	 */
	public String getWord()
	{		
			return word;
	}
	
	/**
	 * Accessor Method - Returns the player's current drawing time in
	 * milliseconds.
	 * @return	drawTime		Player's current drawing time in milliseconds
	 */
	public long getDrawTime()
	{		
		endTime = System.currentTimeMillis();		
		drawTime = endTime - startTime;
		
		return drawTime;
	}
	
	/**
	 * Accessor Method - Returns the player's remaining drawing time in
	 * milliseconds.
	 * @return	timeLeft		Player's remaining drawing time in milliseconds
	 */
	public long getTimeLeft()
	{		
		endTime = System.currentTimeMillis();		
		drawTime = endTime - startTime;
		
		timeLeft  = DRAW_TIME - drawTime;
		
		if(timeLeft < 0)
		{
			return 0;
		}
		else
		{
			return timeLeft;
		}
	}	
	
	/**
	 * Modifier Method - Extracts parameters from data message and performs
	 * functions if necessary.	
	 * @param	DataMessage		Data message
	 * @param	clientIP		Client IP
	 */
	public void parseMessage (DataMessage DataMessage, String clientIP)
	{
		localPack = DataMessage.getLocalPack();
		
		// Extract parameters from data message
		sourceSeqNumber = localPack.getSourceSeqNumber();
		pointsPathLen   = localPack.getPointsPathLen();		
		pointPath       = localPack.getPointPath();	
		word            = localPack.getWord();
		wordType        = localPack.getExtraData();
		hint  			= localPack.getHint();
		hint1           = (String)hint.get(0);		
		hint2           = (String)hint.get(1);	
		guess           = localPack.getAnswer();
		guessTime       = localPack.getGuessTime();
		hintCount       = localPack.getHintCount();
		
		// Check if this is the first data message
		if(firstDataMessage)
		{
			// Start guesser timer
			startTime = System.currentTimeMillis();
			
			// Check if message contains the word to be drawn
			if(word != null)
			{

			}
			else
			{
				// Error, first message should contain the word to be drawn
				dataMessageError = true;
			}
			
			firstDataMessage = false;
		}
		
		// Check for drawing data
		if(pointsPathLen != 0 & pointPath != null)
		{
			// Error, drawer should never receive drawing data from a player
			dataMessageError = true;
		}
		
		if(wordType != null)
		{
			// Error, drawer should never receive the word type
			dataMessageError = true;
		}
		
		if(hint1 != null)
		{
			// Error, drawer should never receive first hint on the word
			dataMessageError = true;
		}
		
		if(hint2 != null)
		{
			// Error, drawer should never receive second hint on the word
			dataMessageError = true;
		}
		
		if(guess != null)
		{
			// Error, drawer should never receive a guess from a player
			dataMessageError = true;
		}
		
		if(guessTime != 0)
		{
			// Error, drawer should never receive a guess time from a player
			dataMessageError = true;
		}
		
		if(hintCount != 0)
		{
			// Error, drawer should never receive the number of hints used by a player
			dataMessageError = true;
		}
	}
	
	/**
	 * Modifier Method - Sends drawing information to server.
	 * @param PointsPathLen		Data points path length
	 * @param PointPath			Array list of points
	 */
	public void draw(int PointsPathLen, ArrayList PointPath)
	{
		pointsPathLen = PointsPathLen;
		pointPath = PointPath;
		
		// End drawer timer
		endTime = System.currentTimeMillis();		
		drawTime = endTime - startTime;
		
		sourceSeqNumber++;
		
		// Check if drawing is within allotted time
		if(drawTime < DRAW_TIME)
		{
			dataMessage = new DataMessage(sourceSeqNumber,pointsPathLen,pointPath,null,null,null,drawTime,0,null);
			
			// send message
		}
	}
}
